

/*$Id: NewKermetaProjectWizard.java,v 1.4 2008-06-09 10:02:23 ftanguy Exp $
 * Project : fr.irisa.triskell.kermeta.kpm
 * File : 	sdfg.java
 * License : EPL
 * Copyright : IRISA / INRIA / Universite de Rennes 1
 * ----------------------------------------------------------------------------
 * Creation date : Feb 20, 2007
 * Authors : ftanguy
 */
package org.kermeta.spem.activityautomation.eclipse.createkermetainterpreterproject.wizards;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.kermeta.spem.executioncontext.ExecutionContext;
import org.kermeta.spem.executioncontext.ExecutioncontextFactory;
import org.kermeta.spem.executioncontext.ExecutioncontextPackage;
import org.kermeta.spem.executioncontext.Key;
import org.kermeta.spem.executioncontext.Value;



public class KermetaProjectNewWizard extends Wizard implements INewWizard {

	KermetaProjectNewWizardPage page = new KermetaProjectNewWizardPage();
	private String contextModelPath;

	public KermetaProjectNewWizard() {
		addPage( page );
	}

	public KermetaProjectNewWizard(String contextModelPath) {
		addPage( page );
		this.contextModelPath = contextModelPath;
	}

	public KermetaProjectNewWizardPage getPage() {
		return page;
	}

	public void addKermetaNatureToProject(IProject project) {
		IProjectDescription description;
		try {
			description = project.getDescription();
			String[] natures = description.getNatureIds();
			String[] newNatures = new String[natures.length + 1];
			System.arraycopy(natures, 0, newNatures, 0, natures.length);
			newNatures[natures.length] = org.kermeta.language.texteditor.eclipse.nature.Activator.NATURE_ID;
			description.setNatureIds(newNatures);
			project.setDescription(description, null);
		} catch (CoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}


	@Override
	public boolean performFinish() {
		try {
			final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(page.getProjectName());
			IWorkspaceRunnable operation = new IWorkspaceRunnable() {
				public void run(IProgressMonitor monitor) throws CoreException {
					project.create(monitor);
					project.open(monitor);
					addKermetaNatureToProject(project);
					createFolder(project, "src/main/kmt", monitor);
					createDefaultKmt(project, "src/main/kmt/MainClass.kmt", monitor);
					createDefaultKp(project, project.getName()+".kp", monitor);
				}
			};
			ResourcesPlugin.getWorkspace().run(operation, null);
		} catch (CoreException exception) {
			exception.printStackTrace();
			return false;
		}

		//Write the compiler name into the context model
		// Initialize the model
		ExecutioncontextPackage.eINSTANCE.eClass();

		// Register the XMI resource factory for the .executioncontext extension

		Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
		Map<String, Object> m = reg.getExtensionToFactoryMap();
		m.put("executioncontext", new XMIResourceFactoryImpl());

		// Obtain a new resource set
		ResourceSet resSet = new ResourceSetImpl();

		// Get the resource
		System.out.println("contextModelPath = "+contextModelPath);
		Resource resource = resSet.getResource(URI
				.createURI(contextModelPath), true);
		// Get the first model element and cast it to the right type, in my
		// example everything is hierarchical included in this first node
		ExecutionContext executionContext = (ExecutionContext) resource.getContents().get(0);

		Key key = ExecutioncontextFactory.eINSTANCE.createKey();
		key.setName("interpreter name");

		Value value = ExecutioncontextFactory.eINSTANCE.createValue();
		value.setContent(page.getProjectName());

		key.setValue(value);
		value.setKey(key);

		executionContext.getKeys().add(key);
		executionContext.getValues().add(value);
		try {
			resource.save(Collections.EMPTY_MAP);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return true;
	}

	public void init(IWorkbench workbench, IStructuredSelection selection) {
	}

	/**
	 * Creates folder hierarchically from a path relative to a project.
	 * @param project
	 * @param path
	 * @param monitor
	 * @throws CoreException
	 */
	private void createFolder(IProject project, String path, IProgressMonitor monitor) throws CoreException {
		String[] strings = path.split("/");
		IContainer currentContainer = project;
		for ( String s : strings ) {
			IFolder folder = currentContainer.getFolder( new Path(s) );
			folder.create(true, true, monitor);
			currentContainer = folder;
		}
	}

	private void createDefaultKp(IProject project,String path,IProgressMonitor monitor) throws CoreException{
		IContainer currentContainer = project;
		IFile file = currentContainer.getFile(new Path(path));

		//String contents = Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.P_NEW_KP_TEMPLATE_STRING);

		//Read the metamodel name and the project metamodel name from the context file
		// Initialize the model
		ExecutioncontextPackage.eINSTANCE.eClass();

		// Register the XMI resource factory for the .executioncontext extension

		Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
		Map<String, Object> m = reg.getExtensionToFactoryMap();
		m.put("executioncontext", new XMIResourceFactoryImpl());

		// Obtain a new resource set
		ResourceSet resSet = new ResourceSetImpl();

		// Get the resource
		Resource resource = resSet.getResource(URI
				.createURI(contextModelPath), true);
		// Get the first model element and cast it to the right type, in my
		// example everything is hierarchical included in this first node
		ExecutionContext executionContext = (ExecutionContext) resource.getContents().get(0);

		String metamodelName = null;
		String projectMetamodelName = null;

		for(Key key : executionContext.getKeys()){
			if(key.getName().equals("project name")){
				projectMetamodelName = key.getValue().getContent();
			}
			if(key.getName().equals("model file name")){
				metamodelName = key.getValue().getContent();
			}
		}

		String contents = "KermetaProject \"${project.name}\"\n    groupId = \"my.group\"\n    defaultMainClass = \"${package.name}::${class.name}\"\n    defaultMainOperation = \"${operation.name}\"\n    sources = {\n        require \"${project.baseUri}/src/main/kmt/${class.name}.kmt\"\n\t\trequire \"${project.baseUri}/src/main/kmt/"+metamodelName+"_context.kmt\"\n\t\trequire \"${project.baseUri}/src/main/kmt/"+metamodelName+"_eval.kmt\"\n\t\trequire \"${"+metamodelName+".model.baseUri}/model/"+metamodelName+".ecore\" byteCodeFromADependency\n    }\n    dependencies = {\n    //default dependency to kermeta framework (try first in eclipse plugin, then look into maven repository)\n    dependency \"library.core\" =\"platform:/plugin/org.kermeta.language.library.core\",\"mvn:org.kermeta.language/language.library.core/2.0.3-SNAPSHOT\"\n\tdependency \""+metamodelName+".model\" = \"platform:/resource/"+projectMetamodelName+"\"\n    }	packageEquivalences={\n    // indicates the real java name of a given package\n    // useful for deployed thirdparty metamodels\n    packageEquivalence \"ecore\" = \"org.eclipse.emf.ecore\"\n    packageEquivalence \"uml\" = \"org.eclipse.uml2.uml\"\n}";

		// replace variables with values from the user
		contents = contents.replaceAll(Pattern.quote("${project.name}"), project.getName());
		contents = contents.replaceAll(Pattern.quote("${class.name}"), "MainClass");
		contents = contents.replaceAll(Pattern.quote("${package.name}"), "mainPackage");
		contents = contents.replaceAll(Pattern.quote("${operation.name}"), "mainOperation");
		try {
			InputStream stream =  new ByteArrayInputStream(contents.getBytes());;
			if (file.exists()) {
				file.setContents(stream, true, true, monitor);
			} else {
				file.create(stream, true, monitor);
			}
			stream.close();
		} catch (IOException e) {
		}
	}



	private void createDefaultKmt(IProject project,String path,IProgressMonitor monitor) throws CoreException{
		IContainer currentContainer = project;
		IFile file = currentContainer.getFile(new Path(path));

		//String contents = Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.P_NEW_KMT_TEMPLATE_STRING);

		String contents = "using kermeta::standard\nusing kermeta::io::StdIO => stdio\n\npackage ${package.name}{\n    class ${class.name}\n    {\n        operation ${operation.name}() : Void is do \n            // TODO: implement '${operation.name}' operation\n            stdio.writeln(\"Hello from ${operation.name}\")\n        end\n    }\n}";

		// replace variables with values from the user
		contents = contents.replaceAll(Pattern.quote("${class.name}"), "MainClass");
		contents = contents.replaceAll(Pattern.quote("${package.name}"), "mainPackage");
		contents = contents.replaceAll(Pattern.quote("${operation.name}"), "mainOperation");

		try {
			InputStream stream =  new ByteArrayInputStream(contents.getBytes());;
			if (file.exists()) {
				file.setContents(stream, true, true, monitor);
			} else {
				file.create(stream, true, monitor);
			}
			stream.close();
		} catch (IOException e) {
		}
	}

}
